package cn.com.lms.business.exam.service;

import cn.com.lms.app.api.exam.vo.EmployeePaperStageDetailVO;
import cn.com.lms.app.api.exam.vo.PaperSubjectVO;
import cn.com.lms.business.core.constant.ErrorEnum;
import cn.com.lms.business.exam.enums.SubjectTypeEnum;
import cn.com.lms.business.exam.persistence.entity.Paper;
import cn.com.lms.business.exam.persistence.entity.PaperSubject;
import cn.com.lms.business.exam.persistence.entity.Question;
import cn.com.lms.business.exam.persistence.entity.QuestionSubject;
import cn.com.lms.business.exam.persistence.repository.PaperSubjectRepository;
import cn.com.lms.business.exam.utils.BeanListUtils;
import com.bnzj.core.persistence.BaseService;



import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

@Service
public class PaperSubjectService extends BaseService<PaperSubjectRepository, PaperSubject, Long> {


    public List<Map<String, Object>> findQuestionSubjectByPaperId(Long paperId) {
        List<Long> paperIdList = Arrays.asList(paperId);
        return repository.findQuestionSubjectByPaperIdList(paperIdList);
    }

    public List<Map> findPaperScoreByPaperIdList(List<Long> paperIdList) {
        return repository.findPaperScoreByPaperIdList(paperIdList);

    }


    public List<Map> findQuestionByPaperId(Long paperId) {
        return repository.findQuestionByPaperId(paperId);
    }


    public Map findPaperSubjectByPaperIdAndSubjectId(Long paperId, Long subjectId) {
        return repository.findPaperSubjectByPaperIdAndSubjectId(paperId, subjectId);
    }

    public List<Map<String,Object>> findPaperSubjectByPaperId(Long paperId) {
        return repository.findPaperSubjectByPaperId(paperId);
    }

    @Transactional(rollbackFor = Exception.class)
    public void batchSave(Paper paper, List<PaperSubject> paperSubjects) {
        if (!CollectionUtils.isEmpty(paperSubjects)) {
            List<PaperSubject> paperSubjectList = paperSubjects.stream().map(paperSubject -> {
                paperSubject.setSortId(paperSubjects.indexOf(paperSubject) + 1);
                paperSubject.setPaperId(paper.getId());
                paperSubject.setCreator(paper.getCreator());
                paperSubject.setCreateTime(paper.getCreateTime());
                paperSubject.setCreatorName(paper.getCreatorName());
                paperSubject.setIsDelete(false);
                return paperSubject;
            }).collect(Collectors.toList());
            super.saveAll(paperSubjects);
        }
    }


    @Transactional
    public int deleteByPaperId(Long paperId) {
        return repository.deleteByPaperId(paperId);
    }

    /**
     * 查询试卷试题列表-固定题
     *
     * @param paperId
     * @return
     */
    public List<PaperSubjectVO> getPaperSubjectVOList(Long paperId) {
        List<PaperSubjectVO> paperSubjectVOList = new CopyOnWriteArrayList<>();
        List<Long> paperIdList = Arrays.asList(paperId);
        List<Map<String, Object>> mapList = repository.findQuestionSubjectByPaperIdList(paperIdList);
        paperSubjectVOList = BeanListUtils.mapListToObjectList(mapList, PaperSubjectVO.class);
         paperSubjectVOList.stream().forEach(paperSubjectVO -> {
             if(SubjectTypeEnum.JUDGE.getValue().shortValue()==paperSubjectVO.getType().shortValue()) {
                 paperSubjectVO.setOptions("A 正确###B 错误");
             }
        });

        return paperSubjectVOList;
    } /**
     * 查询试卷试题列表-随机题
     *
     * @param paperId
     * @return
     */
    public List<PaperSubjectVO> findRadomQuestionSubjectByPaperIdList(Long employeeId,Long paperId) {
        List<PaperSubjectVO> paperSubjectVOList = new CopyOnWriteArrayList<>();
        List<Long> paperIdList = Arrays.asList(paperId);
        List<Map<String, Object>> mapList = repository.findRadomQuestionSubjectByPaperIdList(employeeId,paperIdList);
        paperSubjectVOList = BeanListUtils.mapListToObjectList(mapList, PaperSubjectVO.class);
         paperSubjectVOList.stream().forEach(paperSubjectVO -> {
             if(SubjectTypeEnum.JUDGE.getValue().shortValue()==paperSubjectVO.getType().shortValue()) {
                 paperSubjectVO.setOptions("A 正确###B 错误");
             }
        });

        return paperSubjectVOList;
    }

    /**
     * 查询试卷试题列表-固定题
     *
     * @param paperId
     * @return
     */
    public List<PaperSubjectVO> findRandQuestionSubjectByPaperId(Long paperId) {
        List<PaperSubjectVO> paperSubjectVOList = new CopyOnWriteArrayList<>();
        List<Map<String, Object>> mapList = repository.findRandQuestionSubjectByPaperId(paperId);
        paperSubjectVOList = BeanListUtils.mapListToObjectList(mapList, PaperSubjectVO.class);
        Collections.shuffle(paperSubjectVOList);
        return paperSubjectVOList;
    }

    @Transactional(rollbackFor = Exception.class)
    public void batchSaveRandPaperSubject(EmployeePaperStageDetailVO employeePaperStageDetailVO,String creator) {
        // 保存随机试卷试题
        List<PaperSubjectVO> paperSubjectVOList = employeePaperStageDetailVO.getPaperSubjectVOList();
        List<PaperSubject> paperSubjectList = new CopyOnWriteArrayList<>();
        paperSubjectVOList.stream().forEach(paperSubjectVO -> {
            PaperSubject paperSubject = new PaperSubject();
            paperSubject.setSortId(paperSubjectVOList.indexOf(paperSubjectVO) + 1);
            paperSubject.setPaperId(employeePaperStageDetailVO.getPaperId());
            paperSubject.setCreator(creator);
            paperSubject.setCreateTime(new Date());
            paperSubject.setCreatorName("system");
            paperSubject.setIsDelete(false);
            paperSubject.setSubjectId(paperSubjectVO.getSubjectId().longValue());
            paperSubject.setScore(paperSubjectVO.getScore().intValue());
            paperSubjectList.add(paperSubject);
        });

        saveAll(paperSubjectList);

    }

    /**
     * 试卷生成随机试题
     * @param paperId
     * @param paperSingleScore
     * @param paperMultipleScore
     * @param paperJudgeScore
     * @return
     */
    public  List<PaperSubjectVO> radomPaperSubject(Long paperId,Number paperSingleScore,Number paperMultipleScore,Number paperJudgeScore){
        Integer paperSingleCount = 0;
        Integer paperMultipleCount = 0;
        Integer paperJudgeCount = 0;

        List<PaperSubjectVO> subjectList = new CopyOnWriteArrayList<>();
        List<Map> questionList = this.findQuestionByPaperId(paperId);
        if (!CollectionUtils.isEmpty(questionList)) {
            List<Integer> singleCountList = new CopyOnWriteArrayList<>();
            List<Integer> multipleCountList = new CopyOnWriteArrayList<>();
            List<Integer> judgeCountList = new CopyOnWriteArrayList<>();
            questionList.stream().forEach(questionMap -> {
                Integer singleCount = questionMap.get("singleCount") != null ? Integer.valueOf(questionMap.get("singleCount").toString()) : 0;
                Integer multipleCount = questionMap.get("multipleCount") != null ? Integer.valueOf(questionMap.get("multipleCount").toString()) : 0;
                Integer judgeCount = questionMap.get("judgeCount") != null ? Integer.valueOf(questionMap.get("judgeCount").toString()) : 0;
                singleCountList.add(singleCount);
                multipleCountList.add(multipleCount);
                judgeCountList.add(judgeCount);
            });
            if (!CollectionUtils.isEmpty(singleCountList)) {
                paperSingleCount = singleCountList.stream().collect(Collectors.summingInt(Integer::intValue));
            }
            if (!CollectionUtils.isEmpty(multipleCountList)) {
                paperMultipleCount = multipleCountList.stream().collect(Collectors.summingInt(Integer::intValue));
            }
            if (!CollectionUtils.isEmpty(judgeCountList)) {
                paperJudgeCount = judgeCountList.stream().collect(Collectors.summingInt(Integer::intValue));
            }
        }
        List<PaperSubjectVO> singleSubjectList = new CopyOnWriteArrayList<>();
        List<PaperSubjectVO> multipleSubjectList = new CopyOnWriteArrayList<>();
        List<PaperSubjectVO> judgeSubjectList = new CopyOnWriteArrayList<>();

        List<PaperSubjectVO> paperSubjectVOList = this.findRandQuestionSubjectByPaperId(paperId);
        if (!CollectionUtils.isEmpty(paperSubjectVOList)) {
            singleSubjectList = paperSubjectVOList.stream().filter(m -> SubjectTypeEnum.SINGLE_OPTION.getValue().intValue() == m.getType().intValue()).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(singleSubjectList) && singleSubjectList.size() >= paperSingleCount) {
                Collections.shuffle(singleSubjectList);
                singleSubjectList = singleSubjectList.subList(0, paperSingleCount);
                singleSubjectList = singleSubjectList.stream().map(singleQuestionSubjectVO -> {
                    singleQuestionSubjectVO.setScore(paperSingleScore);
                    return singleQuestionSubjectVO;
                }).collect(Collectors.toList());
                Collections.shuffle(singleSubjectList);
            }

            multipleSubjectList = paperSubjectVOList.stream().filter(m -> SubjectTypeEnum.MULTIPLE_OPTION.getValue().intValue() == m.getType().intValue()).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(multipleSubjectList) && multipleSubjectList.size() >= paperMultipleCount) {
                Collections.shuffle(multipleSubjectList);
                multipleSubjectList = multipleSubjectList.subList(0, paperMultipleCount);
                multipleSubjectList = multipleSubjectList.stream().map(multipleQuestionSubjectVO -> {
                    multipleQuestionSubjectVO.setScore(paperMultipleScore);
                    return multipleQuestionSubjectVO;
                }).collect(Collectors.toList());
                Collections.shuffle(multipleSubjectList);
            }

            judgeSubjectList = paperSubjectVOList.stream().filter(m -> SubjectTypeEnum.JUDGE.getValue().intValue() == m.getType().intValue()).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(judgeSubjectList) && judgeSubjectList.size() >= paperJudgeCount) {
                Collections.shuffle(judgeSubjectList);
                judgeSubjectList = judgeSubjectList.subList(0, paperJudgeCount);


                judgeSubjectList = judgeSubjectList.stream().map(judgeQuestionSubjectVO -> {
                    judgeQuestionSubjectVO.setOptions("A 正确###B 错误");
                    judgeQuestionSubjectVO.setScore(paperJudgeScore);
                    return judgeQuestionSubjectVO;
                }).collect(Collectors.toList());

                Collections.shuffle(judgeSubjectList);
            }
            subjectList.addAll(singleSubjectList);
            subjectList.addAll(multipleSubjectList);
            subjectList.addAll(judgeSubjectList);

        }

        return  subjectList;
    }

    public  List<Map> findBySubjectIdList(List<Long> id) {
        return repository.findPaperBySubjectIdList(id);
    }
}
